Programming for Network Research

Erick Peirson, PhD | erick.peirson@asu.edu | @captbarberousse

Last updated 21 January, 2016

1. First steps with Python.

In this notebook we'll cover some basic concepts for programming in Python. We'll talk about mathematical operations, syntax, and comments.

1.1. Python can math.

Doing math in Python is pretty straightforward. You can add two numbers like this:


In [62]:
1 + 1


Out[62]:
2

...and subtract like this:


In [63]:
1 - 1


Out[63]:
0

Multiplication and division should also look pretty familiar:


In [64]:
4 / 2    # Divide!


Out[64]:
2

In [6]:
4 * 2    # Multiply!


Out[6]:
8

Want to calculate the remainder of a division operation? Use the modulo (%) operator!


In [12]:
5 % 2    # 5 divided by 2 is 2, with a remainder of 1!


Out[12]:
1

To write powers, we use two asterisks (*):


In [13]:
2 ** 5


Out[13]:
32

You can perform multiple operations in a single statement. Python will evaluate your multi-operation statement in the following order:

  1. Power. x ** y
  2. Multiplication, division, modulo. x * y, x / y, x % y
  3. Addition, subtraction. x + y, x - y

In [17]:
5 * 5 - 2 ** 5 - 2


Out[17]:
-9

You can use parentheses to group operations.


In [18]:
5 * (5 - 2) ** (5 - 2)


Out[18]:
135

1.2. Floats and Integers

Suppose I want to divide 5 by 3. You might be tempted to do...


In [19]:
5/3


Out[19]:
1

"What on earth?!" you might ask in incredulity. "Python clearly fails math."

You have just attempted to divide one integer by another. And, as it happens, when you math in Python you will get out what you get in. In this case: an integer (or, in Python, an int).

Of course, we want to deal with all kinds of other real numbers, like 5.1 and $10^-5$. For this we have the floating-point numbers, or float. To write a float, just include a decimal (.):


In [20]:
5.


Out[20]:
5.0

Let's try our elementary-school division problem again, this time with floats:


In [21]:
5./3.


Out[21]:
1.6666666666666667

Tada! That looks much better. If you want to read more about the ins and outs of Python floating point numbers, check out this article.

1.2. Functions.

Often you will need to apply the same set of operations or procedures in a bunch of different places. For example, suppose you need to calculate the area of a circle, $A$, given its radius, $r$. Recall:

$A = \pi r^2$

So if I want to calculate the area of a circle with $r = 5$, I could write:


In [24]:
3.1415927 * 5. ** 2


Out[24]:
78.5398175

This is fine for what it's worth, but if I need to include this calculation in a much larger equation the code will quickly become unreadable. According to the Zen of Python, "Readability counts." And why write it a million times? A good rule to follow is DRY: Don't Repeat Yourself.

So, we define a function (function).


In [25]:
def area_of_a_circle(radius):        # ``radius`` is a "parameter", or "argument".
    return 3.1415927 * radius ** 2   # And we can use it down here!

The first line,

def area_of_a_circle(radius):

is the declaration or signature of the function. This part says, "I hereby define (def) a function called area_of_a_circle. It shall accept a single parameter, which I shall call radius. Let it be so! (:)"

The second line,

return 3.1415927 * radius ** 2

Tells Python what your so-declared function should return. In this case, it returns the outcome of the mathematical operation 3.1415927 * radius ** 2.

Let's try it:


In [26]:
area_of_a_circle(5.)


Out[26]:
78.5398175

Notice this thing we're calling the parameter, radius. radius is a variable. What we've said is that when we call the function, like we just did, whatever we provide as the first (and only) input value should be assigned to a variable called radius. Inside the function, we can use that variable however we like.

We can write as many procedures as we like inside of our function. Suppose, for example, that we wanted to calculate the area of a right cylinder. Recall that:

$A_{cylinder} = 2\pi rh + A_{circle}$

Where $h$ is the height of the cylinder on the axis perpendicular to the radius.

So we could define a function like so:


In [29]:
def area_of_a_cylinder(radius, height):
    area_circle = area_of_a_circle(radius)
    return 2. * 3.1415927 * radius * height + area_circle

First I calculated the area of a circle, and assigned it to a variable called area_circle. Then I calculated the area of the cylinder, using area_circle and the other two parameters (radius and height).


In [30]:
area_of_a_cylinder(5., 12.1)


Out[30]:
458.6725342

1.4. Python can talk.

Well, not really. But it can deal in text just as well as it can deal in numbers.

In Python, a sequence of characters (like the letters in the alphabet, or punctuation marks) is called a string, or str.

We write strings with quotation marks.


In [31]:
"I am a string!"


Out[31]:
'I am a string!'

You can also use single-quotes:


In [32]:
'I am also a string!'


Out[32]:
'I am also a string!'

But they have to match:


In [33]:
'I am going to generate an error!"


  File "<ipython-input-33-dfad34c724f2>", line 1
    'I am going to generate an error!"
                                     ^
SyntaxError: EOL while scanning string literal

You can concatenate strings using the plus (+) operator.


In [34]:
'I am the first part of the string, ' + 'and I am the second part.'


Out[34]:
'I am the first part of the string, and I am the second part.'

We can do all kinds of cool things with strings. For example, we could find out how long a string is using the built-in function len:


In [36]:
len('How long am I?')    # Returns the number of characters.


Out[36]:
14

We can also make strings upper or lower case, or even title case! In an IPython notebook, only the value of the last expression is displayed. So if we want to see the value of multiple expressions in the same cell we'll have to print them.


In [42]:
print 'WHY AM I SCREAMINg?!'.lower()
print "Often this is useful for getting someone's attention".upper()
print 'french people often forget to capitalize proper nouns'.title()


why am i screaming?!
OFTEN THIS IS USEFUL FOR GETTING SOMEONE'S ATTENTION
French People Often Forget To Capitalize Proper Nouns

(if it looks weird to put the function at the end of the string, don't worry; we'll cover that later)

We can get the third character in the string:


In [38]:
mycoolstring = "I'm sick of writing strings, so I'll define a variable."

mycoolstring[2]    # The third character.


Out[38]:
'm'

Notice (!!) that I wrote the number 2 inside of those square braces. Those square braces say, "I want to select the item at a particular index." In this case, 2. But why does 2 select the third element?

In Python, like many (most) programming languages, we count from 0. So mycoolstring[0] gets the first character, mycoolstring[1] gets the second, and mycoolstring[2] the third. It's a little counter-intuitive at first, but after a while you'll find it hard to think in any other way.

Perhaps I want to select a multi-character substring. Say, for example, I want to select the third through the eighth characters:


In [40]:
mycoolstring[2:8]


Out[40]:
'm sick'

Notice (!!) that I wrote the number 8 right there. The colon (:) says "I want to select the items in the range given by these two indices." In this case, 2 and 8. By why 8? Doesn't 8 refer to the ninth element?

In Python, ranges are always inclusive of the start index and exclusive of the end index. So mycoolstring[2:8] selects the characters start with the third element, and up to but not including the ninth element.

Lingo: this is called a slice. Like a slice of pie, but with a string.

1.5. Lists!

Quite often we'll be interested not in just one value, but in whole sequences of values. Perhaps I have measured the length of a whole bunch of widgets, and I want to do some math with those data (e.g. take a mean).

I can store those data in a list. A list is just a sequence of things, where "things" can be just about anything. We write lists with square brackets:


In [44]:
['e', 'r', 'i', 'c', 'k']    # How to spell my name. A list of strings!


Out[44]:
['e', 'r', 'i', 'c', 'k']

In [55]:
widgets = [4.3, 1.2, 8.3, 9.1, 3.3, 5.6, 8.3, 1.2]    # Lengths of widgets.

Just like with strings, I can retrieve items at specific positions in a list.


In [56]:
widgets[1]    # Remember, the --second-- item.


Out[56]:
1.2

I can also select a series of items in the list:


In [57]:
widgets[1:3]    # You can slice lists, too!


Out[57]:
[1.2, 8.3]

Oh, and the last item!


In [58]:
widgets[-1]    # -2 would give the second from last.


Out[58]:
1.2

Let's write a function to calculate the mean. You could re-write this function to calculate the mode!


In [59]:
def mean(sequence):
    """
    This function calculates the mean of a sequence of values.
    """
    return sum(widgets)/len(widgets)    # len() gives the number of widgets.

In [60]:
mean(widgets)


Out[60]:
5.1625

Wrap-up.

In this notebook you learned about...

  • Integers (int) and floating-point numbers (float), and how to do some basic math in Python.
  • How to define simple functions to make your life easier (def cool(param): ...).
  • Strings (str), and some things that you can do with them.
  • Lists (list, []), and some things that you can do with them.
  • String and list indexes (something[4]), and slicing (something[4:7]).

In the next notebook, we'll dive under the covers and talk about objects and types.

Exercises

1.


In [ ]: